package com.bto.solar.work.service;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bto.solar.work.common.BizException;
import com.bto.solar.work.common.RedisService;
import com.bto.solar.work.constant.BizCode;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.constant.DBConstants;
import com.bto.solar.work.dao.IAreaService;
import com.bto.solar.work.dao.ICompanyService;
import com.bto.solar.work.dto.CreateCompanyReq;
import com.bto.solar.work.entity.Area;
import com.bto.solar.work.entity.Company;
import com.bto.solar.work.entity.User;
import com.bto.solar.work.utils.NullUtils;
import com.bto.solar.work.utils.tree.TreeUtils;
import com.bto.solar.work.vo.CompanyVO;
import com.bto.solar.work.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class BtoCompanyService {

    @Autowired
    @Lazy
    private BtoUserService btoUserService;
    @Autowired
    private ICompanyService companyService;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private RedisService redisService;


    /**
     *通过userId获取用户公司
     */
    public Company getCompanyByUserId (Long userId) {
        //获取用户信息
        User user = btoUserService.getUserByUserId(userId);
        //判断用户是否存在
        if (user == null) {
            throw new BizException(BizCode.USER_ABSENT_ERROR);
        }
        return this.getCompanyByUser(user);
    }

    /**
     *通过user获取用户公司
     */
    public Company getCompanyByUser (User user) {
        return companyService.lambdaQuery().eq(Company::getCompanyId, user.getCompanyId()).one();
    }

    /**
     * 通过当前登陆的用户获取可查询的公司（用户管理-查询框-公司类型）
     */
    public List<UserVO.Company> getCompanyByUserQuery() {
        User loginUser = btoUserService.getCurrentUser();
        List<UserVO.Company> companyList;
        //当前登录者为超级管理员或者总部员工
        if (btoUserService.isUserSuperAdmin(loginUser) || btoUserService.isUserBelongHeadCompany(loginUser)) {
            companyList = companyService.lambdaQuery().list().stream()
                    .map(company -> {
                        UserVO.Company userCompany = new UserVO.Company();
                        userCompany.setCompanyId(company.getCompanyId()).setName(company.getName());
                        return userCompany;
                    }).collect(Collectors.toList());
        } else {
            Company company = companyService.lambdaQuery()
                    .eq(Company::getCompanyId, loginUser.getCompanyId()).one();
            UserVO.Company userCompany = new UserVO.Company();
            userCompany.setCompanyId(company.getCompanyId()).setName(company.getName());
            companyList = Collections.singletonList(userCompany);
        }
        return companyList;
    }


    /**
     * 分页显示公司信息
     */
    public Page<CompanyVO> getCompanyVoPage (Integer currentPage, Integer pageSize, boolean orderBy , List<String> types) {

        Page<Company> companyPage = new Page<>(currentPage, pageSize);
        if (orderBy) {
            companyService.lambdaQuery()
                    .eq(Company::getIsDeleted, false)
                    .in(NullUtils.isNotEmpty(types) , Company::getType , types)
                    .orderByDesc(Company::getUpdateTime).page(companyPage);
        } else {
            companyService.lambdaQuery()
                    .eq(Company::getIsDeleted, false)
                    .in(NullUtils.isNotEmpty(types) , Company::getType , types)
                    .orderByAsc(Company::getUpdateTime).page(companyPage);
        }

        List<Company> companyList = companyPage.getRecords();

        //获取全部area
        List<Area> areaList = redisService.getCacheList(Constants.AREA_KEY);
        if (NullUtils.isEmpty(areaList)){
            areaList = areaService.list();
            redisService.setCacheList(Constants.AREA_KEY, areaList);
        }
        Map<Long, Area> areaMap = areaList.stream().collect(Collectors.toMap(Area::getId, area -> area));
        List<CompanyVO> companyVoList = new ArrayList<>();

        for (Company company : companyList) {
            CompanyVO companyVO = new CompanyVO();
            BeanUtils.copyProperties(company, companyVO);

            Area province = areaMap.get(company.getProvinceCode());
            Area city = areaMap.get(company.getCityCode());
            Area district = areaMap.get(company.getDistrictCode());

            String allAddress = province.getName()
                    + city.getName()
                    + district.getName() + company.getAddress();
            companyVO.setAllAddress(allAddress);

            companyVO.setProvince(province);
            companyVO.setCity(city);
            companyVO.setDistrict(district);

            companyVoList.add(companyVO);
        }
        Page<CompanyVO> companyVoPage = new Page<>();
        BeanUtils.copyProperties(companyPage, companyVoPage);
        companyVoPage.setRecords(companyVoList);

        return companyVoPage;
    }

    //提供给注册页面使用
    public List<Company> getCompanyList() {
        List<Company> companyList =  companyService.lambdaQuery().list();
        List<Company> companyNewList = new ArrayList<>();
        companyList.forEach(company -> {
            Company companyNew = new Company();
            companyNew.setCompanyId(company.getCompanyId());
            companyNew.setName(company.getName());
            companyNewList.add(companyNew);
        });
        return companyNewList;
    }


    /**
     * 获取全部地区类型并且构成树
     */
    public List<Area> getAreaInfos(Long areaId) {
        List<Area> areaList = redisService.getCacheList(Constants.AREA_KEY);
        if (NullUtils.isEmpty(areaList)) {
            areaList = areaService.lambdaQuery().list();
            redisService.setCacheList(Constants.AREA_KEY, areaList);
        }
        List<Area> areaByNewList = new ArrayList<>();
        for (Area area : areaList) {
            if (NullUtils.isNull(areaId)) {
                if (DBConstants.AREA_LEVEL_ONE.equals(area.getLevel())) {
                    areaByNewList.add(area);
                }
            } else {
                if (areaId.equals(area.getParentId())) {
                    areaByNewList.add(area);
                }
            }

        }
        return areaByNewList;
    }

    /**
     * 获取全部地区类型并且构成树
     */
    public List<CompanyVO.AreaVO> getAreaInfos() {
        List<Area> areaList = redisService.getCacheList(Constants.AREA_KEY);
        if (NullUtils.isEmpty(areaList)) {
            areaList = areaService.lambdaQuery().list();
            redisService.setCacheList(Constants.AREA_KEY, areaList);
        }
        List<CompanyVO.AreaVO> areaVoList = new ArrayList<>();
        for (Area area : areaList) {
            CompanyVO.AreaVO areaVo = new CompanyVO.AreaVO();
            BeanUtils.copyProperties(area, areaVo);
            areaVoList.add(areaVo);
        }
        Map<String, CompanyVO.AreaVO> areaVoMap =
                areaVoList.stream().collect(Collectors.toMap(area->area.getId().toString(), area -> area));
        return TreeUtils.getTree(areaVoList, areaVoMap);
    }

    /**
     * 获取全部地区类型并且构成Map
     * @return
     */
    public Map<Long, Area> getAreaMap () {
        List<Area> areaList = redisService.getCacheList(Constants.AREA_KEY);
        if (areaList == null){
            areaList = areaService.list();
        }
        return areaList.stream().collect(Collectors.toMap(Area::getId, area -> area));
    }

    /**
     * 新增公司
     */
    public boolean addCompany(CreateCompanyReq createCompanyReq) {
        Company company = new Company();
        //校验公司信息
        this.decideCompany(createCompanyReq, company);
        //添加公司
        return companyService.save(company);
    }

    /**
     * 更新公司信息
     */
    public boolean updateCompany(CreateCompanyReq createCompanyReq) {
        if (NullUtils.isNull(createCompanyReq.getCompanyId())) {
            throw new BizException("公司id不能为空");
        }
        //判断公司是否存在
        Company dbCompany = companyService
                .lambdaQuery().eq(Company::getCompanyId, createCompanyReq.getCompanyId())
                .one();
        if (NullUtils.isNull(dbCompany)) {
            throw new BizException("公司不存在");
        }
        //校验公司信息
        Company company = new Company();
        this.decideCompany(createCompanyReq, company);
        LambdaUpdateWrapper<Company> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Company::getCompanyId, createCompanyReq.getCompanyId());
        //添加公司
        return companyService.update(company, updateWrapper);
    }


    /**
     * 校验公司信息并且完善公司信息
     */
    public void decideCompany (CreateCompanyReq createCompanyReq, Company company) {

        //判断公司名称是否存在
        if (NullUtils.isNull(createCompanyReq) || NullUtils.isEmpty(createCompanyReq.getAreaList())) {
            throw new BizException(BizCode.PARAM_ERROR);
        }

        if (!DBConstants.COMPANY_TYPE_ARRAY.contains(createCompanyReq.getType())) {
            throw new BizException("请选择正确的公司类型！");
        }

        if (createCompanyReq.getAreaList().size() != 3) {
            throw new BizException("请选择正确的区域信息！");
        } else {
            Map<Long, Area> areaMap = this.getAreaMap();

            //验证省份ID
            Area areaByProvinceId = areaMap.get(createCompanyReq.getAreaList().get(0));
            if (NullUtils.isNull(areaByProvinceId)
                    || !areaByProvinceId.getLevel().equals(DBConstants.AREA_LEVEL_ONE)) {
                throw new BizException("省份信息异常！");
            }

            //验证城市ID
            Area areaByCityId = areaMap.get(createCompanyReq.getAreaList().get(1));
            if (NullUtils.isNull(areaByCityId) || !areaByCityId.getLevel().equals(DBConstants.AREA_LEVEL_TWO)
                    || !areaByCityId.getParentId().equals(areaByProvinceId.getId())) {
                throw new BizException("城市信息异常！");
            }

            //验证区/县ID
            Area areaByDistrictId = areaMap.get(createCompanyReq.getAreaList().get(2));
            if (NullUtils.isNull(areaByDistrictId) || !areaByDistrictId.getLevel().equals(DBConstants.AREA_LEVEL_THREE)
                    || !areaByDistrictId.getParentId().equals(areaByCityId.getId())) {
                throw new BizException("区/县信息异常！");
            }
        }
        BeanUtils.copyProperties(createCompanyReq, company);
        company.setProvinceCode(createCompanyReq.getAreaList().get(0));
        company.setCityCode(createCompanyReq.getAreaList().get(1));
        company.setDistrictCode(createCompanyReq.getAreaList().get(2));
    }

    /**
     * 删除公司
     */
    public boolean deleteCompany(Long companyId) {
        //验证公司是否属于当前用户
        List<User> usersList = btoUserService.getUsersByCompanyId(companyId);
        if (NullUtils.isNotEmpty(usersList)) {
            throw new BizException("由用户属于当前公司，删除失败！");
        }
        return companyService.removeById(companyId);

    }

    public Company getCompanyById(Long companyId) {
        return companyService.getById(companyId);
    }
}
